// 类装饰器
function logClass(target: any) {
    return class extends target {
        url = 'world'

        getData() {
            console.log('haha')
        }
    }
}

// 属性装饰器
function logProperty(params: any) {
    // 其中target对于静态成员来说就是类的构造函数，对于实例成员来说就是类的原型对象
    // attr成员的名字，如：url
    return function(target: any, attr: any) {
        target[attr] = params
    }
}

// 方法装饰器
function logMethod(params: any) {
    // 其中target对于静态成员来说就是类的构造函数，对于实例成员来说就是类的原型对象
    // attr成员的名字(方法的名称)，如：getData
    // desc成员的描述符，如desc.value 就是getData(){}
    return function (target: any, attr: any, desc: any) {
        target.url = 'test'
        target.run = function () {}
    }
}

function logParams(params: any) {
    // 其中target对于静态成员来说就是类的构造函数，对于实例成员来说就是类的原型对象
    // attr成员的名字(方法的名称)，如：getData
    // index参数的索引, 如：0
    return function (target: any, attr: any, desc: any) {

    }
}

@logClass
class HttpClient {
    @logProperty('https://www.google.com')
    public url: string | undefined;

    constructor() {}

    // @logMethod('https://www.google.com')
    getData(@logParams('uuid') uuid: any) {
        console.log('获取数据', this.url)
    }
}

// 装饰器的执行顺序 属性->方法->方法参数->类，有多个的话遵循从后向前，从下到上的原则

export {}